package org.dizena.base.aop;

import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
@Slf4j
public class WebLogAspect
{

    @Pointcut("execution(public * org.dizena.modules.*.web..*.*(..))")
    public void log()
    {
    }

    @Pointcut("execution(public * org.dizena.restful..*.*(..))")
    public void api()
    {
    }

    @Around("log()")
    public Object webLog(ProceedingJoinPoint joinPoint) throws Throwable
    {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] paramNames = signature.getParameterNames();
        Class[] classes = signature.getParameterTypes();
        Object[] paramValues = joinPoint.getArgs();
        StringBuilder sb = new StringBuilder();
        if (paramNames != null && paramNames.length > 0)
        {
            for (int i = 0; i < paramNames.length; i++)
            {
                sb.append(classes[i].getName()).append(" ").append(paramNames[i]).append("=");
                if (classes[i].getName().contains("MultipartFile"))
                {
                    sb.append("文件流");
                }
                else if (classes[i].getName().contains("HttpServlet"))
                {
                    sb.append("对象流");
                }
                else if (classes[i].getName().contains("java.lang"))
                {
                    sb.append(paramValues[i]);
                }
                else
                {
                    sb.append(JSON.toJSONString(paramValues[i]));
                }
                sb.append(",");
            }
        }
        String sbStr = sb.toString();
        if (StringUtils.isNotEmpty(sbStr))
        {
            sbStr = sbStr.substring(0, sbStr.length() - 1);
        }
        log.info("{} 请求: {} 执行类: {},方法: {}({})", request.getMethod(), request.getRequestURL(), signature.getDeclaringTypeName(), signature.getName(), sbStr);
        long start = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        long ts = System.currentTimeMillis() - start;
        String resClass = null;
        if (result != null)
        {
            resClass = result.getClass().getName();
        }
        log.info("耗时: {} 毫秒,返回: {}", ts, resClass);
        return result;
    }

    @Around("api()")
    public Object apiLog(ProceedingJoinPoint joinPoint) throws Throwable
    {
        return webLog(joinPoint);
    }

}